# -*- coding: utf-8 -*-
# created on 2016/10/14
from sympy import solveset
from mathsolver.functions.base import *
from mathsolver.functions.yuan.property import ErYuanErCiJudge, ErYuanErCiCoeff
from sympy.abc import x


# 判断方程是否是椭圆
class OvalJudge(BaseFunction):
    def solver(self, *args):
        answer = False
        answer_eryuanerci_judge = ErYuanErCiJudge().solver(args[0]).output[0].sympify()
        if answer_eryuanerci_judge:
            a, b, c, d, e, f = ErYuanErCiCoeff().solver(args[0]).output[0].sympify()
            if (c == 0) and (a * b > 0):
                panbieshi = d ** 2 / (4 * a) + e ** 2 / (4 * b) - f
                if panbieshi > 0 and a > 0 and b > 0:
                    self.steps.append(["", "由椭圆的定义知，该方程是椭圆"])
                    answer = True
                elif panbieshi < 0 and a < 0 and b < 0:
                    self.steps.append(["", "由椭圆的定义知，该方程是椭圆"])
                    answer = True
                else:
                    self.steps.append(["", "由椭圆的定义知，该方程不是椭圆"])
            else:
                self.steps.append(["", "由椭圆的定义知，该方程不是椭圆"])
        else:
            self.steps.append(["", "由椭圆的定义知，该方程不是椭圆"])
        self.output.append(BaseVariable(answer))
        self.label.add("判断方程是否是椭圆")
        return self


# 二元二次方程表示椭圆的条件
class OvalDingYi(BaseFunction):
    def solver(self, *args):
        assert ErYuanErCiJudge().solver(args[0]).output[0].sympify()
        a, b, c, d, e, f = ErYuanErCiCoeff().solver(args[0]).output[0].sympify()
        panbieshi = d ** 2 / (4 * a) + e ** 2 / (4 * b) - f
        ineqs = [[a, "!=", S.Zero], [b, "!=", S.Zero], [c, S.Zero], [a * panbieshi, ">", S.Zero],
                 [a * b, ">", S.Zero], [panbieshi * b, ">", S.Zero]]
        new_ineqs = []
        for item in ineqs:
            if len(item) == 2:
                ineq = Rel(item[0], item[1])
                expr = (item[0] - item[1]).expand().simplify()
            else:
                ineq = Rel(item[0], item[2], item[1])
                expr = (item[0] - item[2]).expand().simplify()
            expr_freesymbols = expr.free_symbols
            if expr_freesymbols:
                symbol = list(expr_freesymbols)[0]
            else:
                symbol = x
            answer = solveset(ineq, symbol, S.Reals)
            if answer != S.Reals:
                new_ineqs.append(item)
        self.steps.append(["由椭圆的定义，得", base_gen(new_ineqs).printing()])
        self.output.append(base_gen(new_ineqs))
        self.label.add("二元二次方程表示椭圆的条件")
        return self


# 焦点在x,y轴上的椭圆条件
class OvalJiaoPointsOnAxis(BaseFunction):
    def solver(self, *args):
        x_coeff, y_coeff = args[0].sympify()
        axis = args[1].sympify()
        if axis[0] == simplify('x'):
            self.steps.append(["", "∵椭圆的焦点在y轴上"])
            self.steps.append(["", "∴%s" % (BaseIneq([x_coeff, "<", y_coeff]).printing())])
            self.output.append(BaseIneq([x_coeff, "<", y_coeff]))
            self.label.add("椭圆的焦点在y轴上成立的条件")
        elif axis[1] == simplify('y'):
            self.steps.append(["", "∵椭圆的焦点在x轴上"])
            self.steps.append(["", "∴%s" % (BaseIneq([x_coeff, ">", y_coeff]).printing())])
            self.output.append(BaseIneq([x_coeff, ">", y_coeff]))
            self.label.add("椭圆的焦点在x轴上成立的条件")
        return self


# 判断方程是否是双曲线
class HyperbolaJudge(BaseFunction):
    def solver(self, *args):
        answer = False
        answer_eryuanerci_judge = ErYuanErCiJudge().solver(args[0]).output[0].sympify()
        if answer_eryuanerci_judge:
            a, b, c, d, e, f = ErYuanErCiCoeff().solver(args[0]).output[0].sympify()
            if (c == 0) and (a * b < 0):
                panbieshi = d ** 2 / (4 * a) + e ** 2 / (4 * b) - f
                if panbieshi != 0:
                    self.steps.append(["", "由双曲线的定义知，该方程是双曲线"])
                    answer = True
                else:
                    self.steps.append(["", "由双曲线的定义知，该方程不是双曲线"])
            else:
                self.steps.append(["", "由双曲线的定义知，该方程不是双曲线"])
        else:
            self.steps.append(["", "由双曲线的定义知，该方程不是双曲线"])
        self.output.append(BaseVariable(answer))
        self.label.add("判断方程是否是双曲线")
        return self


# 二元二次方程表示双曲线的条件
class HyperbolaDingYi(BaseFunction):
    def solver(self, *args):
        assert ErYuanErCiJudge().solver(args[0]).output[0].sympify()
        a, b, c, d, e, f = ErYuanErCiCoeff().solver(args[0]).output[0].sympify()
        panbieshi = d ** 2 / (4 * a) + e ** 2 / (4 * b) - f
        ineqs = [[a * b, "<", S.Zero], [panbieshi, "!=", S.Zero], [c, S.Zero]]
        new_ineqs = []
        for item in ineqs:
            if len(item) == 2:
                ineq = Rel(item[0], item[1])
                expr = (item[0] - item[1]).expand().simplify()
            else:
                ineq = Rel(item[0], item[2], item[1])
                expr = (item[0] - item[2]).expand().simplify()
            expr_freesymbols = expr.free_symbols
            if expr_freesymbols:
                symbol = list(expr_freesymbols)[0]
            else:
                symbol = x
            answer = solveset(ineq, symbol, S.Reals)
            if answer != S.Reals:
                new_ineqs.append(item)
        self.steps.append(["由双曲线的定义，得", base_gen(new_ineqs).printing()])
        self.output.append(base_gen(new_ineqs))
        self.label.add("二元二次方程表示双曲线的条件")
        return self


# 判断方程是否是抛物线
class ParabolaJudge(BaseFunction):
    def solver(self, *args):
        answer = False
        answer_eryuanerci_judge = ErYuanErCiJudge().solver(args[0]).output[0].sympify()
        if answer_eryuanerci_judge:
            a, b, c, d, e, f = ErYuanErCiCoeff().solver(args[0]).output[0].sympify()
            if (c == 0 and b == 0) or (c == 0 and a == 0):
                answer = True
                self.steps.append(["", "由抛物线的定义知，该方程是抛物线"])
            else:
                self.steps.append(["", "由抛物线的定义知，该方程不是抛物线"])
        else:
            self.steps.append(["", "由抛物线的定义知，该方程不是抛物线"])
        self.output.append(BaseVariable(answer))
        self.label.add("判断方程是否是抛物线")
        return


if __name__ == '__main__':
    pass
    # print "oval_judge"
    # for step in oval_judge().solver(BaseEq(["x**2/4+y**2/5","2"])).steps: print step[0], step[1]
    # from mathsolver.functions.fangcheng.budengshi import fangchen_budengshi_002
    # stepsolver = fangchen_budengshi_002().solver(BaseIneqs([["2","!=","0"], ["x",">","4"]])).output[0]

    # print "oval_dingyi"
    # for step in oval_dingyi().solver(BaseEq(["x**2/(k-3)+y**2/(k+3)","1"])).steps: print step[0], step[1]

    # print "hyperbola_judge"
    # for step in hyperbola_judge().solver(BaseEq(["x**2/4-y**2/5", "2"])).steps: print step[0], step[1]

    # print "hyperbola_dingyi"
    # for step in hyperbola_dingyi().solver(BaseEq(["x**2/(2+t)-y**2/(1+t)", "1"])).steps: print step[0], step[1]

    # print "parabola_judge"
    # for step in parabola_judge().solver(BaseEq(["y**2", "2*x"])).steps: print step[0], step[1]

    # print "oval_normalized"
    # for step in oval_normalized().solver(BaseEq(["2*x**2+3*y**2+2*x+4*y", "0"])).steps:
    #     print step[0], step[1]

    # print "hyperbola_normalized"
    # for step in hyperbola_normalized().solver(BaseEq(["2*x**2-3*y**2+2*x+4*y", "0"])).steps:
    #     print step[0], step[1]
